package biz_tools

import (
	"errors"
	"fmt"
	"strconv"
	"time"

	"algo-sdk-go/common/constant"
	commonTools "algo-sdk-go/common/tools"

	"github.com/shopspring/decimal"
)

func GetBMIDesc(height, weight int) string {
	bmi, _ := CalculateBMI(height, weight)
	return GetWeightStatus(bmi)
}

// calculateBMI 計算身體質量指數 (BMI)
// height: 身高 (公尺)
// weight: 體重 (公斤)
// 返回 BMI 值，如果身高 <= 0 則返回 0 和錯誤
func CalculateBMI(height, weight int) (float64, error) {
	if height <= 0 {
		return 0, fmt.Errorf("身高必須大於 0")
	}
	if weight <= 0 {
		return 0, fmt.Errorf("體重必須大於 0")
	}

	heightFloat := decimal.NewFromInt(int64(height)).Div(decimal.NewFromInt(100))
	weightFloat := decimal.NewFromInt(int64(weight)).Div(decimal.NewFromInt(2))

	bmi := weightFloat.Div(heightFloat.Mul(heightFloat)).InexactFloat64()
	return bmi, nil
}

// getWeightStatus 根據 BMI 值判斷體重狀況 (參考亞洲標準)
// bmi: 身體質量指數
// 返回體重狀況描述字串
func GetWeightStatus(bmi float64) string {
	if bmi < 18.5 {
		return "體重過輕 (Underweight)"
	} else if bmi >= 18.5 && bmi < 24 {
		return "正常範圍 (Normal)"
	} else if bmi >= 24 && bmi < 27 {
		return "過重 (Overweight)"
	} else if bmi >= 27 && bmi < 30 {
		return "輕度肥胖 (Mild Obesity)"
	} else if bmi >= 30 && bmi < 35 {
		return "中度肥胖 (Moderate Obesity)"
	} else { // bmi >= 35
		return "重度肥胖 (Severe Obesity)"
	}
}

// ParseAge 解析输入的年份字符串为对应年纪
func ParseAge(yearStr string) (int, error) {
	var year int
	var err error
	currentYear := time.Now().Year()
	// 处理 2 位数字的情况
	if len(yearStr) == 2 {
		yearInt, _ := strconv.Atoi(yearStr)
		if currentYear%100 >= yearInt {
			year = (currentYear/100)*100 + yearInt
		} else {
			year = ((currentYear/100)-1)*100 + yearInt
		}
	} else {
		// 将字符串转换为整数
		year, err = strconv.Atoi(yearStr)
		if err != nil {
			return 0, err
		}
	}
	// 计算年纪
	age := currentYear - year
	return age, nil
}

// 输入时间，获取对应的年龄和生效
func CalculateAgeAndZodiac(birthDateStr string) (int, string, error) {
	// 1. 解析出生日期字符串
	decode, err := commonTools.TimeDecode(&commonTools.TimeFormatParams{TimeStr: birthDateStr})
	if err != nil {
		return 0, "", fmt.Errorf("无效的日期格式: %v", err) // 返回零值和错误
	}
	birthDate := decode.TimeFormat

	// 2. 获取当前日期
	now := commonTools.TimeNow()

	// --- 年龄计算 ---
	// 3. 计算基本年龄差（年份之差）
	age := now.Year() - birthDate.Year()

	// 4. 判断今年的生日是否已过
	if now.Month() < birthDate.Month() || (now.Month() == birthDate.Month() && now.Day() < birthDate.Day()) {
		age--
	}

	// 5. 处理年龄为负数的情况（出生日期在未来）
	if age < 0 {
		return 0, "", errors.New("出生日期不能在未来") // 返回零值和错误
	}

	// --- 生肖计算 (基于公历年) ---
	// 6. 获取出生年份
	birthYear := birthDate.Year()

	// 7. 计算生肖索引
	// (年份 - 4) % 12  映射到 0 (鼠) 到 11 (猪)
	zodiacIndex := (birthYear - 4) % 12
	// 处理可能的负数年份（尽管 time.Parse 可能先报错）
	if zodiacIndex < 0 {
		zodiacIndex += 12
	}

	// 8. 获取生肖名称
	zodiacSign := constant.ChineseZodiacs[zodiacIndex]

	// 9. 返回计算出的年龄、生肖和 nil 错误（表示成功）
	return age, zodiacSign, nil
}
